﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Text;
using BusinessStorage;
using System.IO;
using System.Security.Cryptography;
using System.Xml.Linq;
using System.Web.Security;

namespace OuSuisJeRest
{
    // Start the service and browse to http://<machine_name>:<port>/Service1/help to view the service's generated help page
    // NOTE: By default, a new instance of the service is created for each call; change the InstanceContextMode to Single if you want
    // a single instance of the service to process all calls.	
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    // NOTE: If the service is renamed, remember to update the global.asax.cs file
    public class OuSuisJe 
    {
    
        [WebInvoke(UriTemplate="AuthenticateUser",Method="POST") ]
        public bool AuthenticateUser(UserId user)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            Repository rep = new Repository();
            var ms = rep.GetBlobContainer("keys").GetBlobStream("key");
            ms.Position = 0;
            var doc = XDocument.Load(ms);
            rsa.FromXmlString(doc.ToString());
            //var pass=System.Text.Encoding.UTF8.GetBytes(password);
        
            
            byte[] decBytes = rsa.Decrypt(user.password, true);
            var decrypt = System.Text.Encoding.UTF8.GetString(decBytes, 0, decBytes.Length);
            return Membership.ValidateUser(user.email, decrypt);

           
        }

        [WebGet(UriTemplate = "Enigmas")]
        public List<Enigma> GetEnigmas()
        {

            return new Repository().GetService().Enigmas.Cast<IEnigma>().Cast<Enigma>().ToList();
        }

        [WebGet(UriTemplate = "Responses/ForEnigma/{enigmaid}")]
        public List<Response> GetResponseForEnigma(string enigmaid)
        {
            return new Repository().GetService().Responses.Where(resp=>resp.PartitionKey==enigmaid).Cast<IResponse>().Cast<Response>().ToList();
        }

        [WebInvoke(UriTemplate = "Enigmas", Method = "POST")]
        public void Create(Enigma instance)
        {
            var pl = new BusinessStorage.Enigma(instance.PostalCode, instance.Country, instance.Id) { 
                UserId=instance.UserId,Name=instance.Name,
                Comments=instance.Comments,
             Address=instance.Address,City=instance.City, Latitude=instance.Latitude,Longitude=instance.Longitude,PostDate=DateTime.Now
            };
          
            new Repository().GetService().AddEnigma(pl);
            
        }

        [WebGet(UriTemplate = "Responses/{id}")]
        public Response SelectResp(string id)
        {
            return (Response)((IResponse)SelectResponse(id));
        }

        [WebInvoke(UriTemplate = "Responses", Method = "POST")]
        public void CreateResp(Response instance)
        {

            var resp = new BusinessStorage.Response(instance.EnigmaId, instance.Id)
            {
                UserId = instance.UserId,
                 Content = instance.Content,
                 IsExact = instance.IsExact,
                 PostDate= instance.PostDate
            };
            new Repository().GetService().AddResponse(resp);

        }

        [WebInvoke(UriTemplate = "Reponses/EngimaResolved", Method = "PUT")]
        public void MarkEnigmaAsResolved(string ResponseId)
        {
            var response = SelectResponse(ResponseId);
            response.IsExact = true;
            var enigma = SelectEnigma(response.EnigmaId.ToString());
            enigma.IsFind = true;

            var service=new Repository().GetService();
            service.UpdateResponse(response);
            service.UpdateEnigma(enigma);
        }


        /// <summary>
        /// Création  simple 
        /// </summary>
        /// <param name="instance"></param>
        //[WebInvoke(UriTemplate = "Enigmas/SimpleCreate", Method = "POST")]
        //public void SimpleCreate(string userid, string postalcode, string country, string id)
        //{
        //    var pl = new BusinessStorage.Place(postalcode, country, new Guid(id)) { UserId = new Guid(userid) };
        //    var repo = new Repository();
        //    repo.GetService().AddEnigma(pl);
        //}


        [WebInvoke(UriTemplate = "Enigmas/UploadFile/{id}", Method="POST")]
        public void UploadFile(string id, Stream uploadStream)
        {
            new Repository().GetBlobContainer().CreateBlobFromStream(uploadStream, id);
           
        }


        [WebGet(UriTemplate = "Enigmas/{id}")]
        public Enigma Get(string id)
        {
            return (Enigma)(IEnigma)SelectEnigma(id);
        }

        [WebGet(UriTemplate = "Enigmas/GetFile/{id}")]
        public Stream GetFile(string id)
        {
            WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
            
            var str= new Repository().GetBlobContainer().GetBlobStream(id);
            WebOperationContext.Current.OutgoingResponse.ContentLength = str.Length;
            str.Position = 0;
            return str;
        }


        [WebGet(UriTemplate = "Enigmas/OfUser/{userid}")]
        public List<Enigma> GetUserEnigmas(string userid)
        {
            return new Repository().GetService().GetUserEnigmas(new Guid(userid)).Cast<IEnigma>().Cast<Enigma>().ToList();
        }

        /// <summary>
        /// Returns Enigmas ordered by date, skip and take is available for limit data transfer
        /// </summary>
        /// <param name="skip"></param>
        /// <param name="take"></param>
        /// <returns></returns>
        [WebGet(UriTemplate = "Enigmas/ByDate/{skip}/{take}")]
        public List<Enigma> GetEnigmasOrderedByPostDate(string skip, string take)
        {
            int skipint = int.Parse(skip);
            int takeint = int.Parse(take);
            return new Repository().GetService().GetEnigmasOrderedByPostDate(skipint,takeint).Cast<IEnigma>().Cast<Enigma>().ToList();
        }

        /// <summary>
        /// Find enigmas of my town
        /// </summary>
        /// <param name="postalcode"></param>
        /// <param name="country"></param>
        /// <returns></returns>
        [WebGet(UriTemplate = "Enigmas/AroundMe/{country}/{postalcode}")]
        public List<Enigma> FindEnigmasAroundMe(string postalcode, string country)
        {
            return new Repository().GetService().FindEnigmasAroundMe(postalcode, country).Cast<IEnigma>().Cast<Enigma>().ToList();
        }

        private BusinessStorage.Enigma SelectEnigma(string id)
        {
            return new Repository().GetService().Enigmas.Where(pl => pl.RowKey == id).First();
        }

        private BusinessStorage.Response SelectResponse(string id)
        {
            return new Repository().GetService().Responses.Where(pl => pl.RowKey == id).First();
        }

        [WebInvoke(UriTemplate = "Enigmas/{id}", Method = "PUT")]
        public void Update(string id, Enigma instance)
        {
            var enigma = SelectEnigma(id);
            enigma.Address = instance.Address;
            enigma.City = instance.City;
            enigma.Country = instance.Country;
            enigma.IsFind = instance.IsFind;
            enigma.Latitude = instance.Latitude;
            enigma.Longitude = instance.Longitude;
            enigma.Name = instance.Name;
            enigma.PostalCode = instance.PostalCode;
            new Repository().GetService().UpdateEnigma(enigma);

        }

        [WebInvoke(UriTemplate = "Enigmas/{id}", Method = "DELETE")]
        public void Delete(string id)
        {
            var enigma = SelectEnigma(id);
            new Repository().GetService().UpdateEnigma(enigma);
        }

    }
}
